using System;
using Company.System.IO.IntegrationTests.Properties;

namespace Company.System.IO.IntegrationTests
{
    public class TestBase<TClassUnderTest>
    {
        private const string StringNull = null;
        private const string LocalPath = ".\\";

        protected string SStringNull
        {
            get { return StringNull; }
        }

        protected string SLocalPath
        {
            get { return LocalPath; }
        }

        protected TClassUnderTest ObjectToTest { get; set; }

        protected void ExpectException<TException>(string methodName, Type[] parameterTypes, object[] parameters)
        {
            TestExceptionHelper<TException>.Expect(true, ObjectToTest, methodName, parameterTypes, parameters);
        }

        protected void PathNull_ArgumentNullException(string methodName)
        {
            //Arrange
            Type[] parameterTypes = GetTypeArray<string>();
            object[] parameterValues = GetValueArray(SStringNull);

            //Act
            ExpectException<ArgumentNullException>(methodName, parameterTypes, parameterValues);
        }

        protected void PathEmpty_ArgumentException(string methodName)
        {
            //Arrange
            Type[] parameterTypes = GetTypeArray<string>();
            object[] parameterValues = GetValueArray(string.Empty);

            //Act
            ExpectException<ArgumentException>(methodName, parameterTypes, parameterValues);
        }

        protected void PathContaisOnlyWhitespace_ArgumentException(string methodName)
        {
            //Arrange
            Type[] parameterTypes = GetTypeArray<string>();
            object[] parameterValues = GetValueArray(Resources.PathContainsOnlyWhitspace);

            //Act
            ExpectException<ArgumentException>(methodName, parameterTypes, parameterValues);
        }

        protected void PathContaisOnlyColonChar_ArgumentException(string methodName)
        {
            //Arrange
            Type[] parameterTypes = GetTypeArray<string>();
            object[] parameterValues = GetValueArray(Resources.PathContainsOnlyColonChar);

            //Act
            ExpectException<ArgumentException>(methodName, parameterTypes, parameterValues);
        }

        protected void PathContaisInvalidPathChar_ArgumentException(string methodName)
        {
            //Arrange
            char[] invalidChars = global::System.IO.Path.GetInvalidPathChars();
            Type[] parameterTypes = GetTypeArray<string>();
            object[] parameterValues = GetValueArray(new string(invalidChars));

            //Act
            ExpectException<ArgumentException>(methodName, parameterTypes, parameterValues);
        }

        protected void PathTooLong_PathTooLongException(string methodName, string value)
        {
            //Arrange
            Type[] parameterTypes = GetTypeArray<string>();
            object[] parameterValues = GetValueArray(value);

            //Act
            ExpectException<global::System.IO.PathTooLongException>(methodName, parameterTypes, parameterValues);
        }

        protected void PathUnknown_DirectoryNotFoundException(string methodName, string value)
        {
            //Arrange
            Type[] parameterTypes = GetTypeArray<string>();
            object[] parameterValues = GetValueArray(value);

            //Act
            ExpectException<global::System.IO.DirectoryNotFoundException>(methodName, parameterTypes, parameterValues);
        }

        protected static Type[] GetTypeArray<T1>()
        {
            return new[] {typeof (T1)};
        }

        protected static Type[] GetTypeArray<T1, T2>()
        {
            return new[] {typeof (T1), typeof (T2)};
        }

        protected static Type[] GetTypeArray<T1, T2, T3>()
        {
            return new[] {typeof (T1), typeof (T2), typeof (T3)};
        }

        protected static object[] GetValueArray<T1>(T1 value1)
        {
            return new object[] {value1};
        }

        protected static object[] GetValueArray<T1, T2>(T1 value1, T2 value2)
        {
            return new object[] {value1, value2};
        }

        protected static object[] GetValueArray<T1, T2, T3>(T1 value1, T2 value2, T3 value3)
        {
            return new object[] {value1, value2, value3};
        }
    }
}